package com.zzjson.io.nio.demo;

import lombok.Data;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * <p>****************************************************************************</p>
 * <p><b>Copyright © 2010-2020 shuncom team All Rights Reserved<b></p>
 * <ul style="margin:15px;">
 * <li>Description : com.zzjson.io.nio.demo</li>
 * <li>Version     : 1.0.0</li>
 * <li>Creation    : 2020年02月26日</li>
 * <li>@author     : zzy0_0</li>
 * </ul>
 * <p>****************************************************************************</p>
 */
@Data
public class NIOServer2 {
	private Selector selector;
	private Channel channel;
	private ByteBuffer byteBuffer = ByteBuffer.allocate(10);
	private int port;


	public NIOServer2(int port) {
		try {
			this.port = port;

			ServerSocketChannel channel = ServerSocketChannel.open();

			Selector selector = Selector.open();

			//
			channel.bind(new InetSocketAddress(port));

			channel.configureBlocking(false);

			channel.register(selector, SelectionKey.OP_ACCEPT);

			this.selector = selector;
			this.channel = channel;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void listen() {
		System.out.println("listen port" + port);

		while (true) {
			try {
				selector.select();
				Set<SelectionKey> selectionKeys = selector.selectedKeys();
				Iterator<SelectionKey> iterator = selectionKeys.iterator();
				while (iterator.hasNext()) {
					SelectionKey next = iterator.next();
					iterator.remove();
					process(next);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void process(SelectionKey selectionKey) throws IOException {
		//接受
		if (selectionKey.isAcceptable()) {
			ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel();
			SocketChannel channel = server.accept();
			channel.configureBlocking(false);
			channel.register(selector, SelectionKey.OP_READ);
		} else if (selectionKey.isReadable()) {
			SocketChannel channel = (SocketChannel) selectionKey.channel();
			int len = channel.read(byteBuffer);

			while (len > 0) {
				byteBuffer.flip();
				String name = new String(byteBuffer.array(), 0, len);
				System.out.print(name);
				len = channel.read(byteBuffer);
			}

		}
	}


	public static void main(String[] args) {
		NIOServer2 nioServer2 = new NIOServer2(8080);
		nioServer2.listen();
	}
}
